using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using CKY.AgentPlatform.ModelConfigs;

namespace CKY.AgentPlatform.Agents
{
    /// <summary>
    /// Agent执行应用服务 - 提供Agent执行相关的API接口
    /// </summary>
    public class AgentExecutionAppService : ApplicationService, IAgentExecutionAppService
    {
        private readonly IRepository<Agent, Guid> _agentRepository;
        private readonly IRepository<ModelConfig, Guid> _modelConfigRepository;
        private readonly AgentExecutionEngine _executionEngine;
        private readonly ILogger<AgentExecutionAppService> _logger;

        public AgentExecutionAppService(
            IRepository<Agent, Guid> agentRepository,
            IRepository<ModelConfig, Guid> modelConfigRepository,
            AgentExecutionEngine executionEngine,
            ILogger<AgentExecutionAppService> logger)
        {
            _agentRepository = agentRepository;
            _modelConfigRepository = modelConfigRepository;
            _executionEngine = executionEngine;
            _logger = logger;
        }

        /// <summary>
        /// 执行Agent任务
        /// </summary>
        /// <param name="agentId">Agent ID</param>
        /// <param name="input">执行输入</param>
        /// <returns>执行结果</returns>
        public async Task<AgentExecutionResultDto> ExecuteAsync(Guid agentId, ExecuteAgentInput input)
        {
            _logger.LogInformation("接收到Agent执行请求: {AgentId}, 用户: {UserId}", agentId, input.UserId);

            try
            {
                // 获取Agent配置
                var agent = await _agentRepository.GetAsync(agentId);
                if (!agent.IsActive)
                {
                    throw new InvalidOperationException($"Agent未激活: {agent.Name}");
                }

                // 验证模型配置
                if (agent.ModelConfigId.HasValue)
                {
                    var modelConfig = await _modelConfigRepository.GetAsync(agent.ModelConfigId.Value);
                    if (!modelConfig.IsActive)
                    {
                        throw new InvalidOperationException($"模型配置未激活: {modelConfig.Name}");
                    }
                }

                // 构建执行输入
                var executionInput = new AgentExecutionInput
                {
                    UserInput = input.UserInput,
                    ConversationId = input.ConversationId,
                    UserId = input.UserId,
                    Context = input.Context ?? new Dictionary<string, object>()
                };

                // 执行Agent
                var result = await _executionEngine.ExecuteAsync(agent, executionInput);

                // 返回DTO
                return new AgentExecutionResultDto
                {
                    ExecutionId = result.ExecutionId,
                    Success = result.Success,
                    Response = result.Response,
                    ErrorMessage = result.ErrorMessage,
                    ToolCalls = result.ToolCalls?.Select(tc => new ToolCallResultDto
                    {
                        ToolName = tc.ToolName,
                        Success = tc.Success,
                        Result = tc.Result,
                        ErrorMessage = tc.ErrorMessage
                    }).ToList(),
                    TokensUsed = result.TokensUsed,
                    ExecutionTimeMs = result.ExecutionTimeMs
                };
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Agent执行失败: {AgentId}", agentId);
                return new AgentExecutionResultDto
                {
                    Success = false,
                    ErrorMessage = ex.Message
                };
            }
        }

        /// <summary>
        /// 批量执行Agent任务
        /// </summary>
        /// <param name="input">批量执行输入</param>
        /// <returns>批量执行结果</returns>
        public async Task<BatchExecutionResultDto> BatchExecuteAsync(BatchExecuteAgentInput input)
        {
            _logger.LogInformation("接收到批量Agent执行请求: {Count} 个Agent", input.AgentIds.Count);

            var results = new List<AgentExecutionResultDto>();
            var successCount = 0;
            var failureCount = 0;

            foreach (var agentId in input.AgentIds)
            {
                try
                {
                    var result = await ExecuteAsync(agentId, new ExecuteAgentInput
                    {
                        UserInput = input.UserInput,
                        ConversationId = input.ConversationId,
                        UserId = input.UserId,
                        Context = input.Context
                    });

                    results.Add(result);

                    if (result.Success)
                    {
                        successCount++;
                    }
                    else
                    {
                        failureCount++;
                    }
                }
                catch (Exception ex)
                {
                    failureCount++;
                    results.Add(new AgentExecutionResultDto
                    {
                        Success = false,
                        ErrorMessage = ex.Message
                    });
                }
            }

            return new BatchExecutionResultDto
            {
                TotalCount = input.AgentIds.Count,
                SuccessCount = successCount,
                FailureCount = failureCount,
                Results = results
            };
        }

        /// <summary>
        /// 流式执行Agent任务
        /// </summary>
        /// <param name="agentId">Agent ID</param>
        /// <param name="input">执行输入</param>
        /// <returns>流式执行结果</returns>
        public async IAsyncEnumerable<StreamingExecutionResultDto> ExecuteStreamingAsync(Guid agentId, ExecuteAgentInput input)
        {
            _logger.LogInformation("接收到流式Agent执行请求: {AgentId}", agentId);

            // 获取Agent配置
            Agent agent = null;
            string errorMessage = null;

            try
            {
                agent = await _agentRepository.GetAsync(agentId);
                if (!agent.IsActive)
                {
                    errorMessage = $"Agent未激活: {agent.Name}";
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取Agent失败: {AgentId}", agentId);
                errorMessage = $"获取Agent失败: {ex.Message}";
            }

            if (errorMessage != null)
            {
                yield return new StreamingExecutionResultDto
                {
                    Type = "error",
                    Content = errorMessage
                };
                yield break;
            }

            // 构建执行输入
            var executionInput = new AgentExecutionInput
            {
                UserInput = input.UserInput,
                ConversationId = input.ConversationId,
                UserId = input.UserId,
                Context = input.Context ?? new Dictionary<string, object>()
            };

            // 发送开始事件
            yield return new StreamingExecutionResultDto
            {
                Type = "start",
                ExecutionId = Guid.NewGuid(),
                Content = "开始执行Agent任务"
            };

            // 执行Agent并处理结果
            AgentExecutionResult result;
            string executionError = null;

            try
            {
                // 执行Agent（这里需要修改执行引擎以支持流式处理）
                result = await _executionEngine.ExecuteAsync(agent, executionInput);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "流式Agent执行失败: {AgentId}", agentId);
                executionError = ex.Message;
                result = null;
            }

            if (executionError != null)
            {
                yield return new StreamingExecutionResultDto
                {
                    Type = "error",
                    Content = executionError
                };
                yield break;
            }

            // 发送结果事件
            if (result.Success)
            {
                yield return new StreamingExecutionResultDto
                {
                    Type = "content",
                    Content = result.Response
                };

                if (result.ToolCalls?.Any() ?? false)
                {
                    foreach (var toolCall in result.ToolCalls)
                    {
                        yield return new StreamingExecutionResultDto
                        {
                            Type = "tool_call",
                            Content = $"调用工具: {toolCall.ToolName}",
                            ToolName = toolCall.ToolName,
                            Success = toolCall.Success
                        };
                    }
                }

                yield return new StreamingExecutionResultDto
                {
                    Type = "complete",
                    Content = "执行完成",
                    TokensUsed = result.TokensUsed,
                    ExecutionTimeMs = result.ExecutionTimeMs
                };
            }
            else
            {
                yield return new StreamingExecutionResultDto
                {
                    Type = "error",
                    Content = result.ErrorMessage
                };
            }
        }

        /// <summary>
        /// 获取Agent执行状态
        /// </summary>
        /// <param name="executionId">执行ID</param>
        /// <returns>执行状态</returns>
        public async Task<ExecutionStatusDto> GetExecutionStatusAsync(Guid executionId)
        {
            // 这里需要实现执行状态的查询逻辑
            // 由于当前的执行引擎是同步的，我们可以返回一个模拟的状态
            await Task.CompletedTask;

            return new ExecutionStatusDto
            {
                ExecutionId = executionId,
                Status = "completed",
                StartTime = DateTime.UtcNow.AddSeconds(-5),
                EndTime = DateTime.UtcNow,
                DurationMs = 5000,
                Success = true,
                Progress = 100
            };
        }

        /// <summary>
        /// 停止Agent执行
        /// </summary>
        /// <param name="executionId">执行ID</param>
        /// <returns>停止结果</returns>
        public async Task<StopExecutionResultDto> StopExecutionAsync(Guid executionId)
        {
            // 这里需要实现执行停止的逻辑
            // 由于当前的执行引擎是同步的，我们返回一个模拟的结果
            await Task.CompletedTask;

            return new StopExecutionResultDto
            {
                ExecutionId = executionId,
                Success = false,
                Message = "执行已完成或无法停止"
            };
        }

        /// <summary>
        /// 获取Agent执行历史
        /// </summary>
        /// <param name="agentId">Agent ID</param>
        /// <param name="input">查询参数</param>
        /// <returns>执行历史</returns>
        public async Task<PagedResultDto<ExecutionHistoryDto>> GetExecutionHistoryAsync(Guid agentId, GetExecutionHistoryInput input)
        {
            // 这里需要实现执行历史的查询逻辑
            // 由于当前没有持久化执行记录，我们返回模拟数据
            await Task.CompletedTask;

            var mockHistory = new List<ExecutionHistoryDto>
            {
                new ExecutionHistoryDto
                {
                    ExecutionId = Guid.NewGuid(),
                    UserId = input.UserId,
                    UserInput = "示例输入",
                    Response = "示例响应",
                    Success = true,
                    StartTime = DateTime.UtcNow.AddHours(-1),
                    EndTime = DateTime.UtcNow.AddHours(-1).AddSeconds(30),
                    TokensUsed = 1500,
                    ExecutionTimeMs = 30000
                }
            };

            return new PagedResultDto<ExecutionHistoryDto>(1, mockHistory);
        }

        /// <summary>
        /// 获取Agent执行统计
        /// </summary>
        /// <param name="agentId">Agent ID</param>
        /// <returns>执行统计</returns>
        public async Task<AgentExecutionStatsDto> GetExecutionStatsAsync(Guid agentId)
        {
            var agent = await _agentRepository.GetAsync(agentId);

            // 返回Agent的统计信息
            return new AgentExecutionStatsDto
            {
                AgentId = agentId,
                AgentName = agent.Name,
                TotalExecutions = agent.RunCount,
                SuccessfulExecutions = agent.RunCount - agent.ErrorCount,
                FailedExecutions = agent.ErrorCount,
                SuccessRate = agent.RunCount > 0 ? (agent.RunCount - agent.ErrorCount) * 100.0 / agent.RunCount : 0,
                LastExecutionTime = agent.LastRunTime,
                AverageExecutionTimeMs = 25000, // 模拟数据
                TotalTokensUsed = agent.RunCount * 1500 // 模拟数据
            };
        }
    }

    // DTO定义

    /// <summary>
    /// Agent执行输入DTO
    /// </summary>
    public class ExecuteAgentInput
    {
        public string UserInput { get; set; }
        public Guid? ConversationId { get; set; }
        public Guid UserId { get; set; }
        public Dictionary<string, object> Context { get; set; }
    }

    /// <summary>
    /// Agent执行结果DTO
    /// </summary>
    public class AgentExecutionResultDto
    {
        public Guid ExecutionId { get; set; }
        public bool Success { get; set; }
        public string Response { get; set; }
        public string ErrorMessage { get; set; }
        public List<ToolCallResultDto> ToolCalls { get; set; }
        public long TokensUsed { get; set; }
        public int ExecutionTimeMs { get; set; }
    }

    /// <summary>
    /// 工具调用结果DTO
    /// </summary>
    public class ToolCallResultDto
    {
        public string ToolName { get; set; }
        public bool Success { get; set; }
        public object Result { get; set; }
        public string ErrorMessage { get; set; }
    }

    /// <summary>
    /// 批量执行输入DTO
    /// </summary>
    public class BatchExecuteAgentInput
    {
        public List<Guid> AgentIds { get; set; }
        public string UserInput { get; set; }
        public Guid? ConversationId { get; set; }
        public Guid UserId { get; set; }
        public Dictionary<string, object> Context { get; set; }
    }

    /// <summary>
    /// 批量执行结果DTO
    /// </summary>
    public class BatchExecutionResultDto
    {
        public int TotalCount { get; set; }
        public int SuccessCount { get; set; }
        public int FailureCount { get; set; }
        public List<AgentExecutionResultDto> Results { get; set; }
    }

    /// <summary>
    /// 流式执行结果DTO
    /// </summary>
    public class StreamingExecutionResultDto
    {
        public string Type { get; set; } // start, content, tool_call, complete, error
        public Guid? ExecutionId { get; set; }
        public string Content { get; set; }
        public string ToolName { get; set; }
        public bool? Success { get; set; }
        public long? TokensUsed { get; set; }
        public int? ExecutionTimeMs { get; set; }
    }

    /// <summary>
    /// 执行状态DTO
    /// </summary>
    public class ExecutionStatusDto
    {
        public Guid ExecutionId { get; set; }
        public string Status { get; set; } // running, completed, failed, stopped
        public DateTime StartTime { get; set; }
        public DateTime? EndTime { get; set; }
        public int? DurationMs { get; set; }
        public bool? Success { get; set; }
        public int Progress { get; set; } // 0-100
    }

    /// <summary>
    /// 停止执行结果DTO
    /// </summary>
    public class StopExecutionResultDto
    {
        public Guid ExecutionId { get; set; }
        public bool Success { get; set; }
        public string Message { get; set; }
    }

    /// <summary>
    /// 获取执行历史输入DTO
    /// </summary>
    public class GetExecutionHistoryInput
    {
        public Guid UserId { get; set; }
        public int SkipCount { get; set; }
        public int MaxResultCount { get; set; }
        public DateTime? StartDate { get; set; }
        public DateTime? EndDate { get; set; }
        public bool? SuccessOnly { get; set; }
    }

    /// <summary>
    /// 执行历史DTO
    /// </summary>
    public class ExecutionHistoryDto
    {
        public Guid ExecutionId { get; set; }
        public Guid UserId { get; set; }
        public string UserInput { get; set; }
        public string Response { get; set; }
        public bool Success { get; set; }
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }
        public long TokensUsed { get; set; }
        public int ExecutionTimeMs { get; set; }
    }

    /// <summary>
    /// Agent执行统计DTO
    /// </summary>
    public class AgentExecutionStatsDto
    {
        public Guid AgentId { get; set; }
        public string AgentName { get; set; }
        public int TotalExecutions { get; set; }
        public int SuccessfulExecutions { get; set; }
        public int FailedExecutions { get; set; }
        public double SuccessRate { get; set; }
        public DateTime? LastExecutionTime { get; set; }
        public int AverageExecutionTimeMs { get; set; }
        public long TotalTokensUsed { get; set; }
    }
}